/*
 * tmpfile.c - functions to create and safely open temp files for the shell.
 */

/* Copyright (C) 2000-2015 Free Software Foundation, Inc.

   This file is part of GNU Bash, the Bourne Again SHell.

   Bash is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   Bash is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with Bash.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <config.h>


#if defined (HAVE_UNISTD_H)
#  include <unistd.h>
#endif

#include <bashansi.h>

#include <stdio.h>
#include <stdlib.h>

#include <shell.h>

#define DEFAULT_TMPDIR			P_tmpdir
#define DEFAULT_NAMEROOT		"bash"

static char *
get_tmpdir (flags)
     int flags;
{
  if (flags & MT_USETMPDIR)
    return get_string_value ("TMPDIR") ?: DEFAULT_TMPDIR;
  return DEFAULT_TMPDIR;
}

#if !defined(HAVE_DEV_FD)
/* This is renamed to *_unsafe to trap and review possible additional
 * references when applying the patch to future versions of bash. */
char *
sh_mktmpname_unsafe (nameroot, flags)
     char *nameroot;
     int flags;
{
  char *filename;

  if (asprintf (&filename, "%s/%s.XXXXXX", get_tmpdir (flags),
		nameroot ?: DEFAULT_NAMEROOT) < 0)
    return NULL;
  if (!mktemp (filename) || !*filename)
    {
      free (filename);
      filename = NULL;
    }

  return filename;
}
#endif /* !defined(HAVE_DEV_FD) */

int
sh_mktmpfd (nameroot, flags, namep)
     char *nameroot;
     int flags;
     char **namep;
{
  char *filename;
  int fd = -1;

  if (namep)
    *namep = NULL;
  if (asprintf (&filename, "%s/%s.XXXXXX", get_tmpdir (flags),
		nameroot ?: DEFAULT_NAMEROOT) < 0)
    return -1;
  if ((fd = mkstemp (filename)) < 0)
    {
      free (filename);
      filename = NULL;
    }
  if (namep)
    *namep = filename;
  else
    free (filename);

  return fd;
}

FILE *
sh_mktmpfp (nameroot, flags, namep)
     char *nameroot;
     int flags;
     char **namep;
{
  int fd;
  FILE *fp;

  fd = sh_mktmpfd (nameroot, flags, namep);
  if (fd < 0)
    return NULL;
  fp = fdopen (fd, (flags & MT_READWRITE) ? "w+" : "w");
  if (fp == 0)
    close (fd);
  return fp;
}
